﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Drawing.Imaging;
using System.IO;
using System.Drawing;

namespace OpenPhotoAlbum.Controls.PhotoProcessors
{
	public class Emboss : IPhotoProcessor
	{
		#region IPhotoProcessor Members

		public byte[] Process(byte[] input)
		{
			MemoryStream ms = new MemoryStream(input);
			Bitmap source = new Bitmap(ms);

			int width = source.Width;
			int height = source.Height;

			DateTime t1 = DateTime.UtcNow;

			float[,] srcMatrix = new float[height, width];

			for (int y = 0; y < height; y++)
			{
				for (int x = 0; x < width; x++)
				{
					srcMatrix[y, x] = source.GetPixel(x, y).GetBrightness();
				}
			}

			DateTime t2 = DateTime.UtcNow;

			Color[,] tgtMatrix = new Color[height, width];
			float finalBrightness;
			float currentBrightness;
			List<float> neighbors = new List<float>(4);
			for (int y = 0; y < height; y++)
			{
				for (int x = 0; x < width; x++)
				{
					currentBrightness = srcMatrix[y, x];

					neighbors.Clear();

					if (x > 0) { neighbors.Add(srcMatrix[y, x - 1]); }
					if (x < width - 1) { neighbors.Add(srcMatrix[y, x + 1]); }
					if (y > 0) { neighbors.Add(srcMatrix[y - 1, x]); }
					if (y < height - 1) { neighbors.Add(srcMatrix[y + 1, x]); }

					finalBrightness = 0;
					foreach (float brightness in neighbors)
					{
						finalBrightness += brightness - currentBrightness;
					}
					finalBrightness = finalBrightness / neighbors.Count;

					int value = 64 + (int)(finalBrightness * 1024);

					if (value < 0) { value = 0; }
					else if (value > 255) { value = 255; }

					if (Math.Abs(value - 64) < 8) { value = 64; }

					tgtMatrix[y, x] = Color.FromArgb(value, value, value);
				}
			}

			DateTime t3 = DateTime.UtcNow;

			Bitmap canvas = new Bitmap(width, height);
			for (int y = 0; y < height; y++)
			{
				for (int x = 0; x < width; x++)
				{
					canvas.SetPixel(x, y, tgtMatrix[y, x]);
				}
			}

			DateTime t4 = DateTime.UtcNow;
			System.Diagnostics.Debug.WriteLine(t2.Subtract(t1).TotalMilliseconds);
			System.Diagnostics.Debug.WriteLine(t3.Subtract(t2).TotalMilliseconds);
			System.Diagnostics.Debug.WriteLine(t4.Subtract(t3).TotalMilliseconds);

			ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();

			//find the encoder with the image/jpeg mime-type
			ImageCodecInfo ici = null;
			foreach (ImageCodecInfo codec in codecs)
			{
				if (codec.MimeType == "image/jpeg")
					ici = codec;
			}

			EncoderParameters ep = new EncoderParameters();
			ep.Param[0] = new EncoderParameter(Encoder.Quality, (long)90);

			MemoryStream msResult = new MemoryStream();
			canvas.Save(msResult, ici, ep);

			canvas.Dispose();
			source.Dispose();
			ms.Close();

			return msResult.ToArray();
		}

		#endregion
	}
}
